package com.then.basic.socket.core;

import java.util.LinkedList;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

/**
 *
 * Created by longyi on 16/6/27.
 */
public class NetworkChangeReceiver extends BroadcastReceiver {

    public interface NetworkChangedListener {
        void onNetworkAvailable();
        void onNetworkDisabled();
    }

    private volatile boolean isFirstMessage = false;

    private static final String TAG = "NetworkObserver";

    private static NetworkChangeReceiver sInstance;

    private LinkedList<NetworkChangedListener> listeners = new LinkedList<>();
    private Context appContext;

    public static NetworkChangeReceiver getInstance() {
        return sInstance;
    }

    public static synchronized NetworkChangeReceiver createInstance(Context context) {
        if (sInstance == null) {
            sInstance = new NetworkChangeReceiver(context);
        }
        return sInstance;
    }

    public synchronized static void destroyInstance() {
        if (sInstance != null) {
            sInstance.unregisterSelf();
            sInstance = null;
        }
    }

    public synchronized void registerObserver(NetworkChangedListener listener) {
        if (listeners.isEmpty()) {
            registerSelf();
        }
        if (listeners.indexOf(listener) == -1) {
            listeners.add(listener);
        }
    }

    public synchronized void unregisterObserver(NetworkChangedListener listener) {
        if (listeners.remove(listener)) {
            if (listeners.isEmpty()) {
                unregisterSelf();
            }
        }
    }

    private NetworkChangeReceiver(Context context) {
        super();
        appContext = context.getApplicationContext();
    }

    private void registerSelf() {
        Log.d(TAG, "Register Self");
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        isFirstMessage = true;
        appContext.registerReceiver(this, intentFilter);
    }

    private void unregisterSelf() {
        Log.d(TAG, "Unregister Self");
        try {
            appContext.unregisterReceiver(this);
        } catch (Exception e) {
            Log.e(TAG, "Unregister Self Exception!");
            e.printStackTrace();
        }
    }

    private synchronized void notifyObservers(boolean networkAvailable) {
        for (NetworkChangedListener listener : listeners) {
            if (networkAvailable) {
                listener.onNetworkAvailable();
            } else {
                listener.onNetworkDisabled();
            }
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            if (isFirstMessage) {
                isFirstMessage = false;
                return;
            }
            ConnectivityManager connectivityManager = (ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = connectivityManager.getActiveNetworkInfo();
            if (info != null && info.isAvailable()) {
                Log.d(TAG, "network enabled");
                notifyObservers(true);
            } else {
                Log.d(TAG, "network disabled");
                notifyObservers(false);
            }
        }
    }
}
